import sys
import socket
import threading
import pyodbc
import logging
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import os

# 配置详细日志
logging.basicConfig(
    filename='scanner_debug.log',
    level=logging.DEBUG,
    format='%(asctime)s - %(levelname)s - %(message)s',
    filemode='w'
)
logger = logging.getLogger()


class DatabaseExplorer:
    """数据库深度检查工具"""

    @staticmethod
    def full_inspection(db_path):
        """执行完整的数据库检查"""
        try:
            conn_str = f'DRIVER={{Microsoft Access Driver (*.mdb, *.accdb)}};DBQ={db_path};'
            conn = pyodbc.connect(conn_str)
            cursor = conn.cursor()

            # 1. 检查所有表
            tables = cursor.tables(tableType='TABLE').fetchall()
            logger.info(f"数据库包含 {len(tables)} 张表")

            inspection_result = {
                'tables': {},
                'connection_test': True,
                'error': None
            }

            for table in tables:
                table_name = table.table_name
                logger.info(f"正在检查表: {table_name}")

                table_info = {
                    'columns': [],
                    'sample_data': [],
                    'row_count': 0,
                    'possible_sn_columns': []
                }

                try:
                    # 获取列信息
                    cursor.execute(f"SELECT TOP 1 * FROM [{table_name}]")
                    table_info['columns'] = [column[0] for column in cursor.description]

                    # 获取样本数据
                    table_info['sample_data'] = cursor.execute(
                        f"SELECT TOP 3 * FROM [{table_name}]"
                    ).fetchall()

                    # 获取行数
                    table_info['row_count'] = cursor.execute(
                        f"SELECT COUNT(*) FROM [{table_name}]"
                    ).fetchval()

                    # 识别可能的SN列
                    possible_sn = ['SN', 'Serial', 'SerialNumber', '编号', '条码', 'Barcode', 'Code']
                    table_info['possible_sn_columns'] = [
                        col for col in table_info['columns']
                        if any(sn.lower() in col.lower() for sn in possible_sn)
                    ]

                    # 如果没有找到可能的SN列，检查所有列的数据类型
                    if not table_info['possible_sn_columns']:
                        for col in table_info['columns']:
                            try:
                                sample = cursor.execute(
                                    f"SELECT TOP 1 [{col}] FROM [{table_name}] WHERE [{col}] IS NOT NULL"
                                ).fetchval()
                                if sample and any(c.isalpha() for c in str(sample)):
                                    table_info['possible_sn_columns'].append(col)
                            except:
                                continue

                except Exception as e:
                    logger.error(f"检查表 {table_name} 时出错: {e}")
                    table_info['error'] = str(e)

                inspection_result['tables'][table_name] = table_info

            conn.close()
            return inspection_result

        except Exception as e:
            logger.error(f"数据库检查失败: {e}")
            return {
                'connection_test': False,
                'error': str(e)
            }


class DatabaseManager:
    def __init__(self):
        self.connection = None
        self.db_path = ""
        self.table_info = {}

    def connect(self, db_path):
        """连接数据库并执行完整检查"""
        try:
            self.db_path = db_path
            conn_str = f'DRIVER={{Microsoft Access Driver (*.mdb, *.accdb)}};DBQ={db_path};'
            self.connection = pyodbc.connect(conn_str)
            logger.info(f"成功连接到数据库: {db_path}")

            # 执行完整检查
            self.perform_full_inspection()
            return True
        except Exception as e:
            logger.error(f"数据库连接失败: {e}")
            return False

    def perform_full_inspection(self):
        """执行完整的数据库检查"""
        inspection = DatabaseExplorer.full_inspection(self.db_path)
        if inspection['connection_test']:
            self.table_info = inspection['tables']
            logger.info("数据库检查完成")
            for table, info in self.table_info.items():
                logger.debug(f"表 {table} 信息: {info}")
        else:
            logger.error("数据库检查失败")

    def get_table_columns(self, table_name):
        """获取表的列名"""
        return self.table_info.get(table_name, {}).get('columns', [])

    def query_with_all_methods(self, sn, table_name):
        """尝试所有可能的查询方法"""
        if not self.connection or table_name not in self.table_info:
            logger.error("数据库未连接或表不存在")
            return None

        columns_to_try = self.table_info[table_name].get('possible_sn_columns', [])
        if not columns_to_try:
            columns_to_try = self.table_info[table_name].get('columns', [])

        logger.info(f"将尝试在以下列中查询: {columns_to_try}")

        cursor = self.connection.cursor()

        for column in columns_to_try:
            try:
                # 方法1: 精确匹配
                query = f"SELECT * FROM [{table_name}] WHERE [{column}] = ?"
                cursor.execute(query, sn)
                exact_matches = cursor.fetchall()

                if exact_matches:
                    logger.info(f"在列 {column} 中找到 {len(exact_matches)} 条精确匹配记录")
                    return {
                        'data': exact_matches,
                        'columns': [col[0] for col in cursor.description],
                        'method': f"精确匹配 (列: {column})",
                        'success': True
                    }

                # 方法2: 模糊匹配
                query = f"SELECT * FROM [{table_name}] WHERE [{column}] LIKE ?"
                cursor.execute(query, f'%{sn}%')
                like_matches = cursor.fetchall()

                if like_matches:
                    logger.info(f"在列 {column} 中找到 {len(like_matches)} 条模糊匹配记录")
                    return {
                        'data': like_matches,
                        'columns': [col[0] for col in cursor.description],
                        'method': f"模糊匹配 (列: {column})",
                        'success': True
                    }

                # 方法3: 转换为文本后比较
                query = f"SELECT * FROM [{table_name}] WHERE CSTR([{column}]) LIKE ?"
                cursor.execute(query, f'%{sn}%')
                cast_matches = cursor.fetchall()

                if cast_matches:
                    logger.info(f"在列 {column} 中找到 {len(cast_matches)} 条转换后匹配记录")
                    return {
                        'data': cast_matches,
                        'columns': [col[0] for col in cursor.description],
                        'method': f"文本转换匹配 (列: {column})",
                        'success': True
                    }

            except Exception as e:
                logger.warning(f"查询列 {column} 时出错: {e}")
                continue

        # 如果所有方法都失败，返回无匹配记录的结果
        return {
            'data': [],
            'columns': [],
            'method': "无匹配记录",
            'success': False
        }


class ScannerDebugUI:
    def __init__(self, root):
        self.root = root
        self.root.title("扫码枪数据库查询系统 - 终极调试版")
        self.root.geometry("1200x800")
        
        # 设置文件路径
        self.settings_file = os.path.join(os.path.expanduser("~"), "scanner_settings.ini")
        
        # 记录最后一次选择的表名
        self.last_selected_table = ""

        # 初始化组件
        self.db_manager = DatabaseManager()
        self.server_socket = None
        self.client_socket = None
        self.tcp_mode = "server"  # 默认模式

        # 创建UI
        self.create_tabs()

        # 加载设置并执行自动操作
        self.load_settings()
        self.perform_auto_operations()
        
        # 聚焦到扫码输入框
        self.scan_input.focus_set()

    def create_tabs(self):
        notebook = ttk.Notebook(self.root)

        # 查询标签页
        query_tab = ttk.Frame(notebook)
        self.create_query_tab(query_tab)
        notebook.add(query_tab, text="数据查询")

        # 调试标签页
        debug_tab = ttk.Frame(notebook)
        self.create_debug_tab(debug_tab)
        notebook.add(debug_tab, text="调试工具")

        # 高级标签页
        advanced_tab = ttk.Frame(notebook)
        self.create_advanced_tab(advanced_tab)
        notebook.add(advanced_tab, text="高级设置")

        notebook.pack(expand=True, fill='both')

    def create_query_tab(self, tab):
        # 数据库设置
        db_frame = ttk.LabelFrame(tab, text="数据库设置")
        db_frame.pack(pady=10, padx=10, fill='x')

        # 数据库路径
        path_frame = ttk.Frame(db_frame)
        path_frame.pack(fill='x')
        ttk.Label(path_frame, text="数据库路径:").pack(side=tk.LEFT)
        self.db_path_input = ttk.Entry(path_frame)
        self.db_path_input.pack(side=tk.LEFT, fill='x', expand=True)
        ttk.Button(path_frame, text="浏览...", command=self.browse_db).pack(side=tk.LEFT)

        # 表选择
        table_frame = ttk.Frame(db_frame)
        table_frame.pack(fill='x')
        ttk.Label(table_frame, text="表名:").pack(side=tk.LEFT)
        self.table_combo = ttk.Combobox(table_frame)
        self.table_combo.pack(side=tk.LEFT, fill='x', expand=True)
        # 绑定表选择事件，记录最后一次选择的表
        self.table_combo.bind("<<ComboboxSelected>>", self.on_table_selected)
        ttk.Button(table_frame, text="刷新表", command=self.refresh_tables).pack(side=tk.LEFT)

        # 测试连接
        ttk.Button(db_frame, text="测试数据库连接", command=self.test_connection).pack(pady=5)

        # 扫描输入
        scan_frame = ttk.LabelFrame(tab, text="扫描查询")
        scan_frame.pack(pady=10, padx=10, fill='x')
        self.scan_input = ttk.Entry(scan_frame)
        self.scan_input.pack(pady=5, fill='x')
        self.scan_input.bind("<Return>", lambda event: self.execute_query())
        ttk.Button(scan_frame, text="执行查询", command=self.execute_query).pack(pady=5)

        # 查询结果
        ttk.Label(tab, text="查询结果:").pack(pady=5)
        self.result_display = tk.Text(tab, height=10, state=tk.DISABLED)
        self.result_display.pack(pady=5, fill='both', expand=True)

    def on_table_selected(self, event):
        """表选择事件处理"""
        self.last_selected_table = self.table_combo.get()
        self.save_settings()  # 保存设置，包含最后选择的表

    def create_debug_tab(self, tab):
        # 数据库检查
        inspect_frame = ttk.LabelFrame(tab, text="数据库检查")
        inspect_frame.pack(pady=10, padx=10, fill='x')
        ttk.Button(inspect_frame, text="执行完整数据库检查", command=self.full_inspection).pack(pady=5)
        self.debug_output = tk.Text(inspect_frame, height=10, state=tk.DISABLED)
        self.debug_output.pack(pady=5, fill='both', expand=True)

        # 执行自定义SQL
        sql_frame = ttk.LabelFrame(tab, text="执行自定义SQL")
        sql_frame.pack(pady=10, padx=10, fill='x')
        self.sql_input = tk.Text(sql_frame, height=5)
        self.sql_input.pack(pady=5, fill='both', expand=True)
        ttk.Button(sql_frame, text="执行SQL", command=self.execute_custom_sql).pack(pady=5)
        self.sql_result = tk.Text(sql_frame, height=10, state=tk.DISABLED)
        self.sql_result.pack(pady=5, fill='both', expand=True)

    def create_advanced_tab(self, tab):
        # TCP设置
        tcp_frame = ttk.LabelFrame(tab, text="TCP扫码枪设置")
        tcp_frame.pack(pady=10, padx=10, fill='x')

        # 模式选择
        mode_frame = ttk.Frame(tcp_frame)
        mode_frame.pack(fill='x')
        ttk.Label(mode_frame, text="工作模式:").pack(side=tk.LEFT)
        self.mode_combo = ttk.Combobox(mode_frame, values=["TCP服务端", "TCP客户端"])
        self.mode_combo.current(0)
        self.mode_combo.bind("<<ComboboxSelected>>", self.change_tcp_mode)
        self.mode_combo.pack(side=tk.LEFT)

        # 服务器设置
        self.server_frame = ttk.Frame(tcp_frame)
        server_addr_frame = ttk.Frame(self.server_frame)
        server_addr_frame.pack(fill='x')
        ttk.Label(server_addr_frame, text="监听地址:").pack(side=tk.LEFT)
        self.server_host_input = ttk.Entry(server_addr_frame)
        self.server_host_input.insert(0, "0.0.0.0")
        self.server_host_input.pack(side=tk.LEFT, fill='x', expand=True)
        ttk.Label(server_addr_frame, text="端口:").pack(side=tk.LEFT)
        self.server_port_input = ttk.Entry(server_addr_frame)
        self.server_port_input.insert(0, "12345")
        self.server_port_input.pack(side=tk.LEFT, fill='x', expand=True)

        server_btn_frame = ttk.Frame(self.server_frame)
        server_btn_frame.pack(fill='x')
        self.start_server_btn = ttk.Button(server_btn_frame, text="启动服务器", command=self.start_server)
        self.start_server_btn.pack(side=tk.LEFT)
        self.stop_server_btn = ttk.Button(server_btn_frame, text="停止服务器", command=self.stop_server, state=tk.DISABLED)
        self.stop_server_btn.pack(side=tk.LEFT)

        self.server_frame.pack(pady=5, fill='x')

        # 客户端设置
        self.client_frame = ttk.Frame(tcp_frame)
        client_addr_frame = ttk.Frame(self.client_frame)
        client_addr_frame.pack(fill='x')
        ttk.Label(client_addr_frame, text="服务器地址:").pack(side=tk.LEFT)
        self.client_host_input = ttk.Entry(client_addr_frame)
        self.client_host_input.pack(side=tk.LEFT, fill='x', expand=True)
        ttk.Label(client_addr_frame, text="端口:").pack(side=tk.LEFT)
        self.client_port_input = ttk.Entry(client_addr_frame)
        self.client_port_input.pack(side=tk.LEFT, fill='x', expand=True)

        client_btn_frame = ttk.Frame(self.client_frame)
        client_btn_frame.pack(fill='x')
        self.start_client_btn = ttk.Button(client_btn_frame, text="连接客户端", command=self.start_client)
        self.start_client_btn.pack(side=tk.LEFT)
        self.stop_client_btn = ttk.Button(client_btn_frame, text="断开客户端", command=self.stop_client, state=tk.DISABLED)
        self.stop_client_btn.pack(side=tk.LEFT)

        self.client_frame.pack(pady=5, fill='x')
        self.client_frame.pack_forget()

        # 日志显示
        ttk.Label(tcp_frame, text="TCP日志:").pack(pady=5)
        self.tcp_log = tk.Text(tcp_frame, height=10, state=tk.DISABLED)
        self.tcp_log.pack(pady=5, fill='both', expand=True)

        # 设置
        settings_frame = ttk.LabelFrame(tab, text="系统设置")
        settings_frame.pack(pady=10, padx=10, fill='x')
        self.auto_connect_check = ttk.Checkbutton(settings_frame, text="启动时自动连接数据库")
        self.auto_connect_check.pack(pady=5)
        self.auto_start_tcp_check = ttk.Checkbutton(settings_frame, text="启动时自动启动TCP服务")
        self.auto_start_tcp_check.pack(pady=5)
        ttk.Button(settings_frame, text="保存设置", command=self.save_settings).pack(pady=5)

    def change_tcp_mode(self, event):
        """切换TCP工作模式"""
        mode_text = self.mode_combo.get()
        if mode_text == "TCP服务端":
            self.tcp_mode = "server"
            self.server_frame.pack(pady=5, fill='x')
            self.client_frame.pack_forget()
        else:
            self.tcp_mode = "client"
            self.server_frame.pack_forget()
            self.client_frame.pack(pady=5, fill='x')

    def browse_db(self):
        """浏览数据库文件"""
        path = filedialog.askopenfilename(title="选择Access数据库", filetypes=[("Access数据库", "*.mdb *.accdb")])
        if path:
            self.db_path_input.delete(0, tk.END)
            self.db_path_input.insert(0, path)
            self.refresh_tables()

    def refresh_tables(self):
        """刷新表列表"""
        if not self.db_manager.connect(self.db_path_input.get()):
            return

        tables = list(self.db_manager.table_info.keys())
        self.table_combo['values'] = tables
        
        # 尝试选择最后一次使用的表
        if self.last_selected_table and self.last_selected_table in tables:
            self.table_combo.set(self.last_selected_table)

    def test_connection(self):
        """测试数据库连接"""
        if not self.db_manager.connect(self.db_path_input.get()):
            messagebox.showwarning("错误", "数据库连接失败，请检查日志")
            return

        table_list = "\n".join(self.db_manager.table_info.keys())
        messagebox.showinfo("成功", f"数据库连接成功!\n\n包含的表:\n{table_list}")

    def execute_query(self):
        """执行查询"""
        sn = self.scan_input.get().strip()
        if not sn:
            messagebox.showwarning("警告", "请输入或扫描SN号码")
            return

        table = self.table_combo.get()
        if not table:
            messagebox.showwarning("警告", "请选择表名")
            return

        self.result_display.config(state=tk.NORMAL)
        self.result_display.delete(1.0, tk.END)
        self.result_display.insert(tk.END, f"执行查询: SN='{sn}'\n表名: {table}\n")
        self.result_display.config(state=tk.DISABLED)

        result = self.db_manager.query_with_all_methods(sn, table)

        self.result_display.config(state=tk.NORMAL)
        if result['success']:
            self.result_display.insert(tk.END, f"查询方法: {result['method']}\n")
            self.result_display.insert(tk.END, f"找到 {len(result['data'])} 条记录:\n")
            for row in result['data']:
                row_str = " | ".join([f"{col}: {val}" for col, val in zip(result['columns'], row)])
                self.result_display.insert(tk.END, row_str + "\n")
        else:
            self.result_display.insert(tk.END, result['method'] + "\n")
        self.result_display.config(state=tk.DISABLED)

        self.scan_input.delete(0, tk.END)
        self.scan_input.focus_set()  # 查询后重新聚焦到扫码输入框

    def full_inspection(self):
        """执行完整数据库检查"""
        if not self.db_manager.connect(self.db_path_input.get()):
            return

        self.debug_output.config(state=tk.NORMAL)
        self.debug_output.delete(1.0, tk.END)
        self.debug_output.insert(tk.END, "正在执行完整数据库检查...\n")
        self.debug_output.insert(tk.END, "\n数据库结构:\n")

        for table, info in self.db_manager.table_info.items():
            self.debug_output.insert(tk.END, f"\n表名: {table}\n")
            self.debug_output.insert(tk.END, f"列数: {len(info['columns'])}\n")
            self.debug_output.insert(tk.END, f"行数: {info.get('row_count', '未知')}\n")
            self.debug_output.insert(tk.END, "\n列名:\n")
            self.debug_output.insert(tk.END, ", ".join(info['columns']) + "\n")

            if info['possible_sn_columns']:
                self.debug_output.insert(tk.END, "\n可能的SN字段:\n")
                self.debug_output.insert(tk.END, ", ".join(info['possible_sn_columns']) + "\n")
            else:
                self.debug_output.insert(tk.END, "\n未识别到可能的SN字段\n")

            self.debug_output.insert(tk.END, "\n示例数据:\n")
            for row in info.get('sample_data', []):
                row_str = " | ".join([f"{col}: {val}" for col, val in zip(info['columns'], row)])
                self.debug_output.insert(tk.END, row_str + "\n")

        self.debug_output.insert(tk.END, "\n检查完成!\n")
        self.debug_output.config(state=tk.DISABLED)

    def execute_custom_sql(self):
        """执行自定义SQL"""
        sql = self.sql_input.get(1.0, tk.END).strip()
        if not sql:
            messagebox.showwarning("警告", "请输入SQL语句")
            return

        if not self.db_manager.connection:
            if not self.db_manager.connect(self.db_path_input.get()):
                messagebox.showwarning("错误", "数据库未连接")
                return

        try:
            cursor = self.db_manager.connection.cursor()
            cursor.execute(sql)

            self.sql_result.config(state=tk.NORMAL)
            self.sql_result.delete(1.0, tk.END)
            if sql.lower().startswith("select"):
                # 处理查询结果
                columns = [column[0] for column in cursor.description]
                rows = cursor.fetchall()

                self.sql_result.insert(tk.END, f"查询成功，返回 {len(rows)} 条记录\n")
                self.sql_result.insert(tk.END, "列名: " + ", ".join(columns) + "\n")

                for row in rows:
                    row_str = " | ".join([f"{col}: {val}" for col, val in zip(columns, row)])
                    self.sql_result.insert(tk.END, row_str + "\n")
            else:
                # 处理非查询语句
                self.db_manager.connection.commit()
                self.sql_result.insert(tk.END, "执行成功，影响行数: " + str(cursor.rowcount))
            self.sql_result.config(state=tk.DISABLED)

        except Exception as e:
            self.sql_result.config(state=tk.NORMAL)
            self.sql_result.delete(1.0, tk.END)
            self.sql_result.insert(tk.END, f"SQL执行失败: {str(e)}")
            self.sql_result.config(state=tk.DISABLED)

    def start_server(self):
        """启动TCP服务器"""
        host = self.server_host_input.get()
        port = int(self.server_port_input.get())

        try:
            self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server_socket.bind((host, port))
            self.server_socket.listen(1)
            self.tcp_log.config(state=tk.NORMAL)
            self.tcp_log.insert(tk.END, f"TCP服务器已启动，监听地址: {host}:{port}\n")
            self.tcp_log.config(state=tk.DISABLED)
            self.start_server_btn.config(state=tk.DISABLED)
            self.stop_server_btn.config(state=tk.NORMAL)

            # 启动线程处理客户端连接
            threading.Thread(target=self.accept_connections, daemon=True).start()
        except Exception as e:
            self.tcp_log.config(state=tk.NORMAL)
            self.tcp_log.insert(tk.END, f"服务器启动失败: {str(e)}\n")
            self.tcp_log.config(state=tk.DISABLED)

    def accept_connections(self):
        while True:
            try:
                conn, addr = self.server_socket.accept()
                self.tcp_log.config(state=tk.NORMAL)
                self.tcp_log.insert(tk.END, f"接受连接: {addr}\n")
                self.tcp_log.config(state=tk.DISABLED)
                threading.Thread(target=self.handle_connection, args=(conn,), daemon=True).start()
            except Exception as e:
                if self.server_socket:
                    self.tcp_log.config(state=tk.NORMAL)
                    self.tcp_log.insert(tk.END, f"接受连接时出错: {str(e)}\n")
                    self.tcp_log.config(state=tk.DISABLED)
                break

    def handle_connection(self, conn):
        try:
            while True:
                data = conn.recv(1024)
                if not data:
                    break
                sn = data.decode().strip()
                self.tcp_log.config(state=tk.NORMAL)
                self.tcp_log.insert(tk.END, f"收到数据: {sn}\n")
                self.tcp_log.config(state=tk.DISABLED)
                self.scan_input.delete(0, tk.END)
                self.scan_input.insert(0, sn)
                self.execute_query()
        except Exception as e:
            self.tcp_log.config(state=tk.NORMAL)
            self.tcp_log.insert(tk.END, f"处理连接时出错: {str(e)}\n")
            self.tcp_log.config(state=tk.DISABLED)
        finally:
            conn.close()

    def stop_server(self):
        """停止TCP服务器"""
        if self.server_socket:
            try:
                self.server_socket.close()
                self.tcp_log.config(state=tk.NORMAL)
                self.tcp_log.insert(tk.END, "TCP服务器已停止\n")
                self.tcp_log.config(state=tk.DISABLED)
            except Exception as e:
                self.tcp_log.config(state=tk.NORMAL)
                self.tcp_log.insert(tk.END, f"服务器停止时出错: {str(e)}\n")
                self.tcp_log.config(state=tk.DISABLED)
            self.server_socket = None
            self.start_server_btn.config(state=tk.NORMAL)
            self.stop_server_btn.config(state=tk.DISABLED)

    def start_client(self):
        """启动TCP客户端"""
        host = self.client_host_input.get()
        port = int(self.client_port_input.get())

        try:
            self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.client_socket.connect((host, port))
            self.tcp_log.config(state=tk.NORMAL)
            self.tcp_log.insert(tk.END, f"TCP客户端已连接到 {host}:{port}\n")
            self.tcp_log.config(state=tk.DISABLED)
            self.start_client_btn.config(state=tk.DISABLED)
            self.stop_client_btn.config(state=tk.NORMAL)

            threading.Thread(target=self.receive_data, daemon=True).start()
        except Exception as e:
            self.tcp_log.config(state=tk.NORMAL)
            self.tcp_log.insert(tk.END, f"客户端连接失败: {str(e)}\n")
            self.tcp_log.config(state=tk.DISABLED)

    def receive_data(self):
        try:
            while True:
                data = self.client_socket.recv(1024)
                if not data:
                    break
                sn = data.decode().strip()
                self.tcp_log.config(state=tk.NORMAL)
                self.tcp_log.insert(tk.END, f"收到数据: {sn}\n")
                self.tcp_log.config(state=tk.DISABLED)
                self.scan_input.delete(0, tk.END)
                self.scan_input.insert(0, sn)
                self.execute_query()
        except Exception as e:
            self.tcp_log.config(state=tk.NORMAL)
            self.tcp_log.insert(tk.END, f"接收数据时出错: {str(e)}\n")
            self.tcp_log.config(state=tk.DISABLED)
        finally:
            self.stop_client()

    def stop_client(self):
        """停止TCP客户端"""
        if self.client_socket:
            try:
                self.client_socket.close()
                self.tcp_log.config(state=tk.NORMAL)
                self.tcp_log.insert(tk.END, "TCP客户端已断开连接\n")
                self.tcp_log.config(state=tk.DISABLED)
            except Exception as e:
                self.tcp_log.config(state=tk.NORMAL)
                self.tcp_log.insert(tk.END, f"客户端断开连接时出错: {str(e)}\n")
                self.tcp_log.config(state=tk.DISABLED)
            self.client_socket = None
            self.start_client_btn.config(state=tk.NORMAL)
            self.stop_client_btn.config(state=tk.DISABLED)

    def save_settings(self):
        """保存设置到文件"""
        try:
            with open(self.settings_file, 'w') as f:
                f.write(f"db_path={self.db_path_input.get()}\n")
                f.write(f"auto_connect={1 if self.auto_connect_check.instate(['selected']) else 0}\n")
                f.write(f"auto_start_tcp={1 if self.auto_start_tcp_check.instate(['selected']) else 0}\n")
                f.write(f"tcp_mode={self.tcp_mode}\n")
                f.write(f"server_host={self.server_host_input.get()}\n")
                f.write(f"server_port={self.server_port_input.get()}\n")
                f.write(f"client_host={self.client_host_input.get()}\n")
                f.write(f"client_port={self.client_port_input.get()}\n")
                f.write(f"last_selected_table={self.last_selected_table}\n")
            messagebox.showinfo("成功", "设置已保存")
        except Exception as e:
            messagebox.showerror("错误", f"保存设置失败: {str(e)}")

    def load_settings(self):
        """从文件加载设置"""
        try:
            if os.path.exists(self.settings_file):
                settings = {}
                with open(self.settings_file, 'r') as f:
                    for line in f:
                        key, value = line.strip().split('=', 1)
                        settings[key] = value

                if 'db_path' in settings:
                    self.db_path_input.delete(0, tk.END)
                    self.db_path_input.insert(0, settings['db_path'])
                    self.refresh_tables()

                if 'auto_connect' in settings:
                    if settings['auto_connect'] == '1':
                        self.auto_connect_check.state(['selected'])
                    else:
                        self.auto_connect_check.state(['!selected'])

                if 'auto_start_tcp' in settings:
                    if settings['auto_start_tcp'] == '1':
                        self.auto_start_tcp_check.state(['selected'])
                    else:
                        self.auto_start_tcp_check.state(['!selected'])

                if 'tcp_mode' in settings:
                    self.tcp_mode = settings['tcp_mode']
                    if self.tcp_mode == 'server':
                        self.mode_combo.current(0)
                        self.server_frame.pack(pady=5, fill='x')
                        self.client_frame.pack_forget()
                    else:
                        self.mode_combo.current(1)
                        self.server_frame.pack_forget()
                        self.client_frame.pack(pady=5, fill='x')

                if 'server_host' in settings:
                    self.server_host_input.delete(0, tk.END)
                    self.server_host_input.insert(0, settings['server_host'])

                if 'server_port' in settings:
                    self.server_port_input.delete(0, tk.END)
                    self.server_port_input.insert(0, settings['server_port'])

                if 'client_host' in settings:
                    self.client_host_input.delete(0, tk.END)
                    self.client_host_input.insert(0, settings['client_host'])

                if 'client_port' in settings:
                    self.client_port_input.delete(0, tk.END)
                    self.client_port_input.insert(0, settings['client_port'])

                if 'last_selected_table' in settings:
                    self.last_selected_table = settings['last_selected_table']

        except Exception as e:
            messagebox.showerror("错误", f"加载设置失败: {str(e)}")

    def perform_auto_operations(self):
        """执行自动操作"""
        # 自动连接数据库
        if self.auto_connect_check.instate(['selected']):
            db_path = self.db_path_input.get()
            if db_path and os.path.exists(db_path):
                if self.db_manager.connect(db_path):
                    self.refresh_tables()
                    self.tcp_log.config(state=tk.NORMAL)
                    self.tcp_log.insert(tk.END, "已自动连接数据库\n")
                    self.tcp_log.config(state=tk.DISABLED)
                else:
                    self.tcp_log.config(state=tk.NORMAL)
                    self.tcp_log.insert(tk.END, "自动连接数据库失败\n")
                    self.tcp_log.config(state=tk.DISABLED)

        # 自动启动TCP服务
        if self.auto_start_tcp_check.instate(['selected']):
            if self.tcp_mode == 'server':
                self.start_server()
            else:
                self.start_client()

    def on_closing(self):
        """关闭程序时清理资源"""
        self.stop_server()
        self.stop_client()
        self.root.destroy()


if __name__ == "__main__":
    root = tk.Tk()
    app = ScannerDebugUI(root)
    root.protocol("WM_DELETE_WINDOW", app.on_closing)
    root.mainloop()
